package models

import (
	"errors"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
	"strconv"
	"time"
)

type Menus struct {
	Id        int       `orm:"column(id);auto" description:"pk_id" json:"id" form:"id"`
	Name      string    `orm:"column(name);size(50)" description:"菜单名称" json:"name" form:"name"`
	Level     int8      `orm:"column(level)" description:"菜单等级" json:"level" form:"level"`
	Icon      string    `orm:"column(icon);size(20);null" description:"菜单图标" json:"icon" form:"icon"`
	Top       *Menus    `orm:"column(top_id);null;rel(fk)" description:"上级菜单ID" json:"top" form:"top_id"`
	Url       string    `orm:"column(url);size(100);null" description:"菜单地址" json:"url" form:"url"`
	Order     int       `orm:"column(order);null" description:"序号" json:"order" form:"order"`
	CreatedAt time.Time `orm:"column(created_at);type(datetime);null" description:"创建时间" json:"created_at" form:"created_at"`
	UpdatedAt time.Time `orm:"column(updated_at);type(datetime);null" description:"更新时间" json:"updated_at" form:"updated_at"`
}

// 定义表名
func (m *Menus) TableName() string {
	return "menus"
}

// 初始化表
func init() {
	orm.RegisterModel(new(Menus))
}

// 添加Role
func (m *Menus) AddMenus() (err error) {
	o := orm.NewOrm()
	m.CreatedAt = time.Now()
	m.UpdatedAt = time.Now()
	// 校验结构体是否通过
	if err = m.Validation(); err != nil {
		return
	}
	id, err := o.Insert(m)
	// 校验是否插入成功
	if err != nil {
		return
	}
	// 将插入后的ID反射到结构体
	strInt64 := strconv.FormatInt(id, 10)
	m.Id, _ = strconv.Atoi(strInt64)
	return
}

// 根据id删除Role
func (m *Menus) DeleteMenusById() (err error) {
	o := orm.NewOrm()
	// 执行删除
	_, err = o.Delete(&Menus{Id: m.Id})
	return
}

// 根据ID修改Role
func (m *Menus) UpdateMenusById() (err error) {
	o := orm.NewOrm()
	m.UpdatedAt = time.Now()
	// 校验结构体是否通过
	if err = m.Validation(); err != nil {
		return
	}
	// 执行修改
	_, err = o.Update(m)
	return
}

// 根据id获取Role结构体
func (m *Menus) GetMenusById() (err error) {
	o := orm.NewOrm()
	qs := o.QueryTable(m)
	err = qs.Filter("id", m.Id).RelatedSel().One(m)
	if err != nil {
		return err
	}
	return
}

// 校验结构体
func (m *Menus) Validation() (err error) {
	valid := validation.Validation{}
	valid.Required(m.Name, "name").Message("菜单名称不能为空")
	valid.MaxSize(m.Name, 20, "usernameMax").Message("菜单名称不能大于20位")
	valid.Required(m.Level, "level").Message("菜单等级不能为空")
	valid.Range(m.Level, 1, 3, "levelMax").Message("菜单等级必须为1~3之间")
	// 第一次校验
	if valid.HasErrors() {
		for _, err := range valid.Errors {
			return err
		}
	}
	// 第二次校验
	o := orm.NewOrm().QueryTable(Menus{})
	if flag := o.Exclude("id", m.Id).Filter("name", m.Name).Exist(); flag {
		return errors.New("菜单名称已经存在,请更换菜单名称")
	}
	if m.Top.Id != 0 {
		if flag := o.Filter("id", m.Top.Id).Exist(); !flag {
			return errors.New("上级菜单不存在,请刷新后重试")
		}
	}
	return
}
